package com.qing.picture.service.impl;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qing.picture.exception.BusinessException;
import com.qing.picture.exception.ErrorCode;
import com.qing.picture.exception.ThrowUtils;
import com.qing.picture.model.dto.analyze.*;
import com.qing.picture.model.entity.Picture;
import com.qing.picture.model.entity.Space;
import com.qing.picture.model.entity.User;
import com.qing.picture.service.PictureService;
import com.qing.picture.service.SpaceAnalyzeService;
import com.qing.picture.service.SpaceService;
import com.qing.picture.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SpaceAnalyzeServiceImpl implements SpaceAnalyzeService {
    @Resource
    private UserService userService;

    @Resource
    private SpaceService spaceService;

    @Resource
    private PictureService pictureService;

    /**
     * TODO 空间分析权限校验
     */
    private void checkSpaceAnalyzeAuth(SpaceAnalyzeRequest analyzeRequest, User loginuser){
        //访问公共空间校验权限
        if(analyzeRequest.isQueryAll() || analyzeRequest.isQueryPublic()){
            ThrowUtils.throwIf(!userService.isAdmin(loginuser), ErrorCode.OPERATION_ERROR,"权限不足，无法查询所有空间信息");
        }else{
            //访问私有空间校验权限
            ThrowUtils.throwIf(analyzeRequest.getSpaceId() == null||analyzeRequest.getSpaceId()<=0, ErrorCode.PARAMS_ERROR);
            Space space = spaceService.getById(analyzeRequest.getSpaceId());
            ThrowUtils.throwIf(space == null, ErrorCode.OPERATION_ERROR,"空间不存在");
            ThrowUtils.throwIf(!userService.isAdmin(loginuser) && !space.getUserId().equals(loginuser.getId()),ErrorCode.OPERATION_ERROR,"权限不足，无法访问该空间");
        }
    }

    /**
     *  查询条件分析
     */

    private static void finllAnalyzeQueryWrapper(SpaceAnalyzeRequest analyzeRequest, QueryWrapper<Picture> queryWrapper){
        /**
         *  查询所有空间
         */
        if(analyzeRequest.isQueryAll()){
            return;
        }

        /**
         *  查询公共空间
         */
        if(analyzeRequest.isQueryPublic()){
            queryWrapper.isNull("spaceId");
            return;
        }

        /**
         *  查询私有空间
         */
        Long spaceId = analyzeRequest.getSpaceId();
        if(spaceId != null){
            queryWrapper.eq("spaceId", spaceId);
            return;
        }
        throw new BusinessException(ErrorCode.PARAMS_ERROR,"查询条件不在范围内");
    }

    /**
     * 空间使用分析
     * @param analyzeRequest
     * @param loginuser
     * @return
     */
    @Override
    public SpaceUsageAnalyzeResponse getSpaceUsageAnalyze(SpaceUsageAnalyzeRequest analyzeRequest, User loginuser) {
        ThrowUtils.throwIf(analyzeRequest == null, ErrorCode.PARAMS_ERROR,"请求参数不能为空");
       // TODO 权限校验
        checkSpaceAnalyzeAuth(analyzeRequest,loginuser);

        //查询参数
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        finllAnalyzeQueryWrapper(analyzeRequest,queryWrapper);

        //查询结果
        SpaceUsageAnalyzeResponse analyzeResponse = new SpaceUsageAnalyzeResponse();

        if(analyzeRequest.isQueryAll() || analyzeRequest.isQueryPublic()){
            //公共空间
            queryWrapper.select("picSize");
            if(!analyzeRequest.isQueryAll()){
                queryWrapper.isNull("spaceId");
            }

            List<Picture> pictureList = pictureService.list(queryWrapper);
            long usedSize = pictureList.stream().mapToLong(Picture::getPicSize).sum();
            long usedCount = pictureList.size();

            analyzeResponse.setUsedCount(usedSize);
            analyzeResponse.setUsedSize(usedCount);

            /**
             * TODO 公共空间无上限、比例
             */
            analyzeResponse.setMaxSize(null);
            analyzeResponse.setMaxCount(null);
            analyzeResponse.setSizeUsageRatio(null);
            analyzeResponse.setCountUsageRatio(null);
            return analyzeResponse;
        }else{
            //私有空间
            Space space = spaceService.getById(analyzeRequest.getSpaceId());

            analyzeResponse.setUsedCount(space.getTotalCount());
            analyzeResponse.setUsedSize(space.getMaxSize());

            analyzeResponse.setMaxCount(space.getMaxCount());
            analyzeResponse.setMaxSize(space.getMaxSize());

            double sizeUsageRatio = NumberUtil.round(space.getTotalSize()*100.0 / space.getMaxSize(),2).doubleValue();
            double countUsageRatio = NumberUtil.round(space.getTotalCount()*100.0 / space.getTotalCount(),2).doubleValue();

            analyzeResponse.setSizeUsageRatio(sizeUsageRatio);
            analyzeResponse.setCountUsageRatio(countUsageRatio);
            return analyzeResponse;
        }
    }

    /**
     * 根据分类分析
     * @param analyzeRequest
     * @param loginuser
     * @return
     */
    @Override
    public List<SpaceCategoryAnalyzeResponse> getSpaceCategoryAnalyze(SpaceCategoryAnalyzeRequest analyzeRequest, User loginuser) {
       ThrowUtils.throwIf(analyzeRequest == null, ErrorCode.PARAMS_ERROR,"请求参数不能为空");
       // 校验权限
        checkSpaceAnalyzeAuth(analyzeRequest,loginuser);

        // 查询参数
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        finllAnalyzeQueryWrapper(analyzeRequest,queryWrapper);


           queryWrapper.select(("category as category"), ("Count(*) as count"), ("SUM(picSize) as totalSize")).groupBy("category");

            // 查询并转换结果
            return pictureService.getBaseMapper().selectMaps(queryWrapper)
                    .stream()
                    .map(result -> {
                        String category = result.get("category") != null ? result.get("category").toString() : "未分类";
                        Long count = ((Number) result.get("count")).longValue();
                        Long totalSize = ((Number) result.get("totalSize")).longValue();
                        return new SpaceCategoryAnalyzeResponse(category, count, totalSize);
                    })
                    .collect(Collectors.toList());
    }

    @Override
    public List<SpaceTagAnalyzeResponse> getSpaceTagAnalyze(SpaceTagAnalyzeRequest analyzeRequest, User loginuser) {
        ThrowUtils.throwIf(analyzeRequest == null, ErrorCode.PARAMS_ERROR, "请求参数不能为空");
        // 校验权限
        checkSpaceAnalyzeAuth(analyzeRequest, loginuser);

        // 查询参数
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        finllAnalyzeQueryWrapper(analyzeRequest, queryWrapper);

        // 查询所有符合条件的标签
        queryWrapper.select("tags");
        List<String> tagsJsonList = pictureService.getBaseMapper().selectObjs(queryWrapper)
                .stream()
                .filter(ObjUtil::isNotNull)
                .map(Object::toString)
                .collect(Collectors.toList());

        // 合并所有标签并统计使用次数
        Map<String, Long> tagCountMap = tagsJsonList.stream()
                .flatMap(tagsJson -> JSONUtil.toList(tagsJson, String.class).stream())
                .collect(Collectors.groupingBy(tag -> tag, Collectors.counting()));

        // 转换为响应对象，按使用次数降序排序
        return tagCountMap.entrySet().stream()
                .sorted((e1, e2) -> Long.compare(e2.getValue(), e1.getValue())) // 降序排列
                .map(entry -> new SpaceTagAnalyzeResponse(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }

    @Override
    public List<SpaceUserAnalyzeResponse> getSpaceUserAnalyze(SpaceUserAnalyzeRequest spaceUserAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceUserAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);
        // 检查权限
        checkSpaceAnalyzeAuth(spaceUserAnalyzeRequest, loginUser);

        // 构造查询条件
        QueryWrapper<Picture> queryWrapper = new QueryWrapper<>();
        Long userId = spaceUserAnalyzeRequest.getUserId();
        queryWrapper.eq(ObjUtil.isNotNull(userId), "userId", userId);
        finllAnalyzeQueryWrapper(spaceUserAnalyzeRequest, queryWrapper);

        // 分析维度：每日、每周、每月
        String timeDimension = spaceUserAnalyzeRequest.getTimeDimension();
        switch (timeDimension) {
            case "day":
                queryWrapper.select("DATE_FORMAT(createTime, '%Y-%m-%d') AS period", "COUNT(*) AS count");
                break;
            case "week":
                queryWrapper.select("YEARWEEK(createTime) AS period", "COUNT(*) AS count");
                break;
            case "month":
                queryWrapper.select("DATE_FORMAT(createTime, '%Y-%m') AS period", "COUNT(*) AS count");
                break;
            default:
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "不支持的时间维度");
        }

        // 分组和排序
        queryWrapper.groupBy("period").orderByAsc("period");

        // 查询结果并转换
        List<Map<String, Object>> queryResult = pictureService.getBaseMapper().selectMaps(queryWrapper);
        return queryResult.stream()
                .map(result -> {
                    String period = result.get("period").toString();
                    Long count = ((Number) result.get("count")).longValue();
                    return new SpaceUserAnalyzeResponse(period, count);
                })
                .collect(Collectors.toList());
    }
    @Override
    public List<Space> getSpaceRankAnalyze(SpaceRankAnalyzeRequest spaceRankAnalyzeRequest, User loginUser) {
        ThrowUtils.throwIf(spaceRankAnalyzeRequest == null, ErrorCode.PARAMS_ERROR);

        // 仅管理员可查看空间排行
        ThrowUtils.throwIf(!userService.isAdmin(loginUser), ErrorCode.NO_AUTH_ERROR, "无权查看空间排行");

            // 构造查询条件
        QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "spaceName", "userId", "totalSize")
                .orderByDesc("totalSize")
                .last("LIMIT " + spaceRankAnalyzeRequest.getTopN()); // 取前 N 名

        // 查询结果
        return spaceService.list(queryWrapper);
    }

}
